
#include <mockcpp/mockcpp.hpp>
#include <testngpp/testngpp.hpp>
#include <Measurement.h>
#include <Length.h>
#include <Volume.h>

USING_MOCKCPP_NS
USING_TESTNGPP_NS

FIXTURE(TestMeasurement)
{
	TEST("should be able to judge 1 mile equals 1760 yards")
	{
	    Measurement mile(1, MILE);
            Measurement yard(1760, YARD);
	    ASSERT_TRUE(mile == yard);
	}

	TEST("should be able to judge 1 mile does not equal to 1750 yards")
	{
	    Measurement mile(1, MILE);
            Measurement yard(1750, YARD);
	    ASSERT_TRUE(mile != yard);
	}

	TEST("should be able to judge 1 yard equals 3 feet")
	{
	    Measurement yard(1, YARD);
            Measurement feet(3, FEET);
	    ASSERT_TRUE(yard == feet);
	}

	TEST("should be able to judge 1 yard does not equal 4 feet")
	{
	    Measurement yard(1, YARD);
            Measurement feet(4, FEET);
	    ASSERT_TRUE(yard != feet);
	}

        TEST("should be able to judge 1 mile equals 1760*3=5280 feet")
	{
	    Measurement yard(1, MILE);
            Measurement feet(5280, FEET);
	    ASSERT_TRUE(yard == feet);
	}

        TEST("should be able to judge 1 mile dequals 5281 feet")
	{
	    Measurement yard(1, MILE);
            Measurement feet(5281, FEET);
	    ASSERT_TRUE(yard != feet);
	}

        TEST("should be able to judge 1 oz equals 3 tsp")
	{
	    Measurement oz(1, OZ);
            Measurement tsp(3, TSP);
	    ASSERT_TRUE(oz == tsp);
	}

        TEST("should be able to judge 1 oz dequals 4 tsp")
	{
	    Measurement oz(1, OZ);
            Measurement tsp(4, TSP);
	    ASSERT_TRUE(oz != tsp);
	}

        TEST("should be able to judge 1 tsp equals 4 tbsp")
	{
	    Measurement tsp(1, TSP);
            Measurement tbsp(4, TBSP);
	    ASSERT_TRUE(tsp == tbsp);
	}

        TEST("should be able to judge 1 tsp equals 5 tbsp")
	{
	    Measurement tsp(1, TSP);
            Measurement tbsp(5, TBSP);
	    ASSERT_TRUE(tsp != tbsp);
	}

        TEST("should be able to judge 1 mile dequals 1 oz")
	{
	    Measurement mile(1, MILE);
            Measurement oz(1, OZ);
	    ASSERT_TRUE(mile != oz);
	}

        TEST("should be able to do the length addition calculation: 1Mile+1760Yard=2Mile")
	{
	    Measurement mile(1, MILE);
            Measurement yard(1760, YARD);
	    ASSERT_EQ(Measurement(2, MILE), mile + yard);
	}

        TEST("should be able to do the volume addition calculation: 1Oz+3TSP=2Oz")
	{
	    Measurement oz(1, OZ);
            Measurement tsp(3, TSP);
	    ASSERT_EQ(Measurement(2, OZ), oz + tsp);
	}

        TEST("should be able to judge OZ cannot be added with MILE: 1Oz+1MILE=INVALID")
	{
	    Measurement oz(1, OZ);
            Measurement mile(1, MILE);
	    ASSERT_TRUE(Measurement(INVALID_OPERATION, MILE) == oz + mile);
	}

        //can not be compiled
        //TEST("should not be able to define a new Unit by the client")
	//{
        //    UnitType unitTypeArea;
        //    Unit unitSquareMeter(100, unitTypeArea);
        //}
};

FIXTURE(PrintMode1, "Test for print model 1:xx MILE xx YARD xx FEET")
{
        TEST("should be able to display like '1 MILE 21 YARD' for 1781 yards")
	{
	    Measurement length(1781, YARD);
	    ASSERT_TRUE("1 MILE 21 YARD" == length.toString());
	}

        TEST("should be able to display like '1 YARD 2 FEET' for 5 feet")
	{
	    Measurement length(5, FEET);
	    ASSERT_TRUE("1 YARD 2 FEET" == length.toString());
	}

        TEST("should be able to display like '1 MILE 2 FEET' for 5282 feet")
	{
	    Measurement length(5282, FEET);
	    ASSERT_TRUE("1 MILE 2 FEET" == length.toString());
	}

        TEST("should be able to display like '0 FEET' for 0 mile")
	{
	    Measurement length(0, MILE);
	    ASSERT_TRUE("0 FEET" == length.toString());
	}
};

FIXTURE(PrintMode2, "Test for print model 2:xx FEET")
{
        TEST("should be able to display like '10560 FEET' for 2 mile")
	{
	    Measurement length(2, MILE);
	    ASSERT_TRUE("10560 FEET" == length.toString(STRING_BASE_UNIT_PRINT_MODE));
	}

        TEST("should be able to display like '30 FEET' for 10 yard")
	{
	    Measurement length(10, YARD);
	    ASSERT_TRUE("30 FEET" == length.toString(STRING_BASE_UNIT_PRINT_MODE));
	}

        TEST("should be able to display like '10 FEET' for 10 feet")
	{
	    Measurement length(10, FEET);
	    ASSERT_TRUE("10 FEET" == length.toString(STRING_BASE_UNIT_PRINT_MODE));
	}

        TEST("should be able to display like '0 FEET' for 0 mile")
	{
	    Measurement length(0, MILE);
	    ASSERT_TRUE("0 FEET" == length.toString(STRING_BASE_UNIT_PRINT_MODE));
	}

};
